﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Golos.Helper;
using Golos.Polls.PollCache;
using Golos.Users.UserCache;

namespace Golos.Polls.Http
{
	public partial class PollCacheServer
	{
	    private void GetTop10Question(HttpListenerContext context, ref int statusCode)
	    {
            try
            {
                List<Guid> questionIds = pollCache.GetTop10Question();
                byte[] data = new byte[0];
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        foreach (var questionId in questionIds)
                        {
                            writer.WriteLine(questionId);
                        }
                        writer.Flush();
                    }
                    data = stream.ToArray();
                }
                context.Response.ContentLength64 = data.LongLength;
                context.Response.ContentEncoding = Encoding.Default;
                context.Response.OutputStream.Write(data, 0, data.Length);
                statusCode = (int)HttpStatusCode.OK;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry(exception.ToString());
                statusCode = (int)HttpStatusCode.InternalServerError;
            }
	    }

	    private void GetPoll(HttpListenerContext context, ref int statusCode)
	    {
            try
            {
                if (context.Request.QueryString.AllKeys.Contains("questionid"))
                {
                    Guid questionId = new Guid(context.Request.QueryString["questionid"]);
                    PollInfo pollInfo = pollCache.GetPollByQuestionId(questionId);
                    if (pollInfo == null)
                    {
                        statusCode = (int)HttpStatusCode.NotFound;
                        return;
                    }
                    byte[] data = pollInfo.Serialize();
                    context.Response.ContentLength64 = data.LongLength;
                    context.Response.ContentEncoding = Encoding.Default;
                    context.Response.OutputStream.Write(data, 0, data.Length);
                    statusCode = (int)HttpStatusCode.OK;
                    return;
                }
                statusCode = (int) HttpStatusCode.BadRequest;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry(exception.ToString());
                statusCode = (int)HttpStatusCode.InternalServerError;
            }
	    }

	    private void CheckUserAnswer(HttpListenerContext context, ref int statusCode)
	    {
            try
            {
                if (context.Request.QueryString.AllKeys.Contains("questionid") && context.Request.QueryString.AllKeys.Contains("userid"))
                {
                    Guid questionId = new Guid(context.Request.QueryString["questionid"]);
                    Guid userId = new Guid(context.Request.QueryString["userid"]);
                    UserAnswerInfo userAnswerInfo = pollCache.CheckUserAnswer(questionId, userId);
                    if(userAnswerInfo==null)
                    {
                        statusCode = (int) HttpStatusCode.NotFound;
                        return;
                    }
                    byte[] data = userAnswerInfo.Serialize();
                    context.Response.ContentLength64 = data.LongLength;
                    context.Response.ContentEncoding = Encoding.Default;
                    context.Response.OutputStream.Write(data, 0, data.Length);
                    statusCode = (int)HttpStatusCode.OK;
                    return;
                }
                statusCode = (int)HttpStatusCode.BadRequest;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry(exception.ToString());
                statusCode = (int)HttpStatusCode.InternalServerError;
            }
	    }

	    private void GetVoicesCount(HttpListenerContext context, ref int statusCode)
	    {
            try
            {
                if (context.Request.QueryString.AllKeys.Contains("questionid"))
                {
                    Guid questionId = new Guid(context.Request.QueryString["questionid"]);
                    Dictionary<Guid, int> voicesCount = pollCache.GetVoicesCount(questionId);
                    byte[] data = new byte[0];
                    if(voicesCount.Count>0)
                        using(MemoryStream stream = new MemoryStream())
                        {
                            using(StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
                            {
                                foreach (Guid answerId in voicesCount.Keys)
                                {
                                    writer.WriteLine(string.Format("{0}\t{1}", answerId, voicesCount[answerId]));
                                }
                                writer.Flush();
                            }
                            data = stream.ToArray();
                        }
                    context.Response.ContentLength64 = data.LongLength;
                    context.Response.ContentEncoding = Encoding.Default;
                    context.Response.OutputStream.Write(data, 0, data.Length);
                    statusCode = (int)HttpStatusCode.OK;
                    return;
                }
                statusCode = (int)HttpStatusCode.BadRequest;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry(exception.ToString());
                statusCode = (int)HttpStatusCode.InternalServerError;
            }
	    }


	    private void GetMyQuestion(HttpListenerContext context, ref int statusCode)
	    {
            try
            {
                if (context.Request.QueryString.AllKeys.Contains("userid") && context.Request.QueryString.AllKeys.Contains("type"))
                {
                    Guid userId = new Guid(context.Request.QueryString["userid"]);
                    string type = context.Request.QueryString["type"];
                    List<Guid> questionIds;
                    switch (type.ToUpperInvariant())
                    {
                        case "OWNER" :
                            questionIds = pollCache.GetUserQuestions(userId);
                            break;
                        case "VOTED":
                            questionIds = pollCache.GetVotedQuestions(userId);
                            break;
                        default :
                            statusCode = (int)HttpStatusCode.BadRequest;
                            return;
                    }
                    byte[] data = new byte[0];
                    if(questionIds.Count>0)
                        using (MemoryStream stream = new MemoryStream())
                        {
                            using (StreamWriter writer = new StreamWriter(stream))
                            {
                                foreach (var questionId in questionIds)
                                {
                                    writer.WriteLine(questionId);
                                }
                                writer.Flush();
                            }
                            data = stream.ToArray();
                        }
                    context.Response.ContentLength64 = data.LongLength;
                    context.Response.ContentEncoding = Encoding.Default;
                    context.Response.OutputStream.Write(data, 0, data.Length);
                    statusCode = (int)HttpStatusCode.OK;
                    return;
                }
                statusCode = (int)HttpStatusCode.BadRequest;
                return;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry(exception.ToString());
                statusCode = (int)HttpStatusCode.InternalServerError;
            }
	    }

	    private void SearchPoll(HttpListenerContext context, ref int statusCode)
	    {
            try
            {
                if (context.Request.QueryString.AllKeys.Contains("keyword"))
                {
                    string keyword = Encoding.UTF8.GetString(Convert.FromBase64String(context.Request.QueryString["keyword"]));
                    List<Guid> questionIds = pollCache.SearchPollInDb(keyword);
                    byte[] data = new byte[0];
                    if (questionIds.Count > 0)
                        using (MemoryStream stream = new MemoryStream())
                        {
                            using (StreamWriter writer = new StreamWriter(stream))
                            {
                                foreach (var questionId in questionIds)
                                {
                                    writer.WriteLine(questionId);
                                }
                                writer.Flush();
                            }
                            data = stream.ToArray();
                        }
                    context.Response.ContentLength64 = data.LongLength;
                    context.Response.ContentEncoding = Encoding.Default;
                    context.Response.OutputStream.Write(data, 0, data.Length);
                    statusCode = (int)HttpStatusCode.OK;
                    return;
                }
                statusCode = (int)HttpStatusCode.BadRequest;
                return;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry(exception.ToString());
                statusCode = (int)HttpStatusCode.InternalServerError;
            }
	    }
	}
}
